package com.trace.pplos.parse.job;

import com.alibaba.fastjson.JSON;
import com.trace.pplos.parse.common.CompressUtils;
import com.trace.pplos.parse.common.Constant;
import com.trace.pplos.parse.common.DateUtils;
import com.trace.pplos.parse.common.ParseEnum;
import com.trace.pplos.parse.dao.dataobject.*;
import com.trace.pplos.parse.service.*;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by goldzql on 2017/8/8.
 */
@Component
public class ScheduledJob {
    private static final Logger logger = LoggerFactory.getLogger(ScheduledJob.class);

    @Autowired
    private Constant constant;

    @Autowired
    private ClwzInfoService clwzInfoService;

    @Autowired
    private CzrkInfoService czrkInfoService;

    @Autowired
    private CzwInfoService czwInfoService;

    @Autowired
    private GgaqdwInfoService ggaqdwInfoService;

    @Autowired
    private LdrkInfoService ldrkInfoService;

    @Autowired
    private MqmyInfoService mqmyInfoService;

    @Autowired
    private TzhyInfoService tzhyInfoService;

    @Autowired
    private WpxxInfoService wpxxInfoService;

    @Autowired
    private YjldInfoService yjldInfoService;

    @Autowired
    private ZdcsInfoService zdcsInfoService;

    @Autowired
    private ZdryInfoService zdryInfoService;

    @Autowired
    private WifiInfoService wifiInfoService;

    @Autowired
    private CjcjInfoService cjcjInfoService;

    @Autowired
    private HjrkInfoService hjrkInfoService;

    @Scheduled(cron="0/10 * * * * ?")
    public void executeFileDownLoadTask() {
        long beginTime = System.currentTimeMillis();
        File file = new File(constant.getTarget());
        File[] listFiles= file.listFiles();
        int fileCount = listFiles.length;
        logger.info("ScheduledJob start：{}，count：{}", beginTime, fileCount);
        if(fileCount > 0){
            int corePoolSize = 5;
            int maximumPoolSize = 10;
            long keepActiveTime = 200;
            TimeUnit timeUnit = TimeUnit.SECONDS;
            BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(20);
            ThreadPoolExecutor pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepActiveTime, timeUnit,workQueue);
            for(int i=0;i<fileCount;i++){
                File parseFile = listFiles[i];
                FileParseThread thread = new FileParseThread(parseFile);
                pool.execute(thread);
            }
            pool.shutdown();
            while (true) {
                if (pool.isTerminated()) {
                    long diff = System.currentTimeMillis()-beginTime;
                    logger.info("ScheduledJob end，count：{}，exec：{}", fileCount, (diff/1000));
                    break;
                }
            }
        }
    }

    class FileParseThread extends Thread{

        private File parseFile;

        public File getParseFile() {
            return parseFile;
        }

        public void setParseFile(File parseFile) {
            this.parseFile = parseFile;
        }

        public FileParseThread(File parseFile){
            this.parseFile = parseFile;
        }

        @Override
        public void run(){
            String fileName = getParseFile().getName();
            String uncompressPath = constant.getUncompress();
            if(fileName.startsWith(ParseEnum.CLWZ.getCode())){
                uncompressPath += ParseEnum.CLWZ.getCode()+File.separator+ DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    ClwzInfo info = ClwzInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        clwzInfoService.insert(info);
                    }else{
                        logger.error(ParseEnum.CLWZ.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.CZRK.getCode())){
                uncompressPath += ParseEnum.CZRK.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    CzrkInfo info = CzrkInfo.toBean(object);
                    if(info != null){
                        czrkInfoService.insert(info);
                    }else{
                        logger.error(ParseEnum.CZRK.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.CZW.getCode())){
                uncompressPath += ParseEnum.CZW.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    CzwInfo info = CzwInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        czwInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.CZW);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.CZW.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.AQDW.getCode())){
                uncompressPath += ParseEnum.AQDW.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    GgaqdwInfo info = GgaqdwInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        ggaqdwInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.AQDW);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.AQDW.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.LDRK.getCode())){
                uncompressPath += ParseEnum.LDRK.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    LdrkInfo info = LdrkInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        ldrkInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.LDRK);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.LDRK.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.MQMY.getCode())){
                uncompressPath += ParseEnum.MQMY.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    MqmyInfo info = MqmyInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        mqmyInfoService.insert(info);
                    }else{
                        logger.error(ParseEnum.MQMY.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.TZHY.getCode())){
                uncompressPath += ParseEnum.TZHY.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    TzhyInfo info = TzhyInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        tzhyInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.TZHY);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.TZHY.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.WPXX.getCode())){
                uncompressPath += ParseEnum.WPXX.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    WpxxInfo info = WpxxInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        wpxxInfoService.insert(info);
                    }else{
                        logger.error(ParseEnum.WPXX.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.YJDP.getCode())){
                uncompressPath += ParseEnum.YJDP.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    YjldInfo info = YjldInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        yjldInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.YJDP);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.YJDP.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.ZDCS.getCode())){
                uncompressPath += ParseEnum.ZDCS.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    ZdcsInfo info = ZdcsInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        zdcsInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.ZDCS);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.ZDCS.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.ZDRY.getCode())){
                uncompressPath += ParseEnum.ZDRY.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    ZdryInfo info = ZdryInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        zdryInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.ZDRY);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.ZDRY.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.CJCJ.getCode())){
                uncompressPath += ParseEnum.CJCJ.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    CjcjInfo info = CjcjInfo.toBean(object);
                    if(info != null){
                        info.setFilepath(uncompressPath);
                        cjcjInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.CJCJ);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.CJCJ.getRemark(), "failed", object);
                    }
                }
            }else if(fileName.startsWith(ParseEnum.SYRK.getCode())){
                uncompressPath += ParseEnum.SYRK.getCode()+File.separator+DateUtils.getDate()+File.separator;
                String object = fileParseBackup(uncompressPath);
                if(object != null){
                    HjrkInfoWithBLOBs info = HjrkInfoWithBLOBs.toBean(object);
                    if(info != null){
                        //info.setFilepath(uncompressPath);
                        hjrkInfoService.insert(info);
                        List<WifiInfo> list = WifiInfo.toBean(object, info.getId(), ParseEnum.CJCJ);
                        for (int i = 0; i < list.size(); i++) {
                            wifiInfoService.insert(list.get(i));
                        }
                    }else{
                        logger.error(ParseEnum.SYRK.getRemark(), "failed", object);
                    }
                }
            }else{
                logger.info("ScheduledJob unknown fileName：{}", fileName);
                return;
            }
        }

        //文件解压、内容解析、备份
        private String fileParseBackup(String uncompressPath){
            try {
                boolean flag = CompressUtils.unZipFiles(getParseFile().getAbsolutePath(), uncompressPath );
                if(flag){
                    String content = FileUtils.readFileToString(new File(uncompressPath+"data.json"), "utf-8");
                    //getParseFile().renameTo(new File(constant.getSuccess()+DateUtils.getDate()+File.separator+getParseFile().getName()));
                    FileUtils.moveFile(getParseFile(),
                            new File(constant.getSuccess()+DateUtils.getDate()+File.separator+getParseFile().getName())
                    );
                    logger.info("fileParseBackup success, source:{},target:{}", getParseFile().getAbsolutePath(), (constant.getSuccess()+DateUtils.getDate()+File.separator+getParseFile().getName()));
                    return content;
                }else{
                    FileUtils.moveFile(getParseFile(),
                            new File(constant.getFailed()+DateUtils.getDate()+File.separator+getParseFile().getName())
                    );
                    logger.error("fileParseBackup failed, source:{},target:{}", getParseFile().getAbsolutePath(), (constant.getFailed()+DateUtils.getDate()+File.separator+getParseFile().getName()));
                }
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
            return null;
        }
    }
}